// 引入axios
import axios from 'axios'

// 
// 可以把固定的参数进行一个封装，然后再实现请求拦截
// (method) AxiosStatic.create(config?: AxiosRequestConfig): AxiosInstance
// create方法接收一个请求配置对象，返回一个实例
const Axios = axios.create({
    timeout: 5000,
    baseURL: '/apis'
})

// 可以使用实例的拦截属性来进行请求拦截 -- 发起请求之前，请求响应之后
// 请求之前做一个拦截
// 函数会把请求参数全部传参进来，我们可以对这个参数做处理
// 请求前的拦截，需要返回数据，才会继续发出请求
Axios.interceptors.request.use(function(config) {
    console.log(config)
    // 如果token不存在则直接抛出一个错误，然后结束请求，不然请求发出去
    // let token = ''
    // 模拟有token数据
    let token = 'U2FsdGVkX18s+vFiHvFo27xcZQlFVdidkTmXuJaEikuoZ8lhQG++60s5aFdbxh5tBOJvApPlNPxtEFYKZMMWd5mXe4UauKuo/858oz9r950='

    // 是所有的接口都要拦截 -- 有一些接口是不需要拦截的
    // 对请求地址进行过滤，如果不是不需要拦截接口使用拦截
    // 定义一个数组，然后把所有的不需要拦截地址在这里进行定义
    let otherPath = ['/user/app/code','/api/tabs?sa=0','/api/tab/1/feeds?start=20&sort=20']

    // 如果请求地址包含在排除地址中，那么这个请求就不需要拦截
    if (otherPath.includes(config.url)) {
        return config
    } else {
        // 如果需要拦截，则需要对token进行校验
        // 不存在，直接返回一个错误信息
        if (!token) {
            return Promise.reject({code: 400, message: '当前用户没有登录，所以不能发出异步请求'})
        } else {
            // 可以对config数据进行加工，添加上token数据
            config.headers.token = token
            // 直接发出请求
            return config
        }
    }

    
})

// 响应之后 -- 需要使用use方法来注册一个钩子函数，用于axios再完成请求之后来执行业务处理方法
// (method) AxiosInterceptorManager.use(onFulfilled?: (value: AxiosResponse) => Promise | any)
// use 需要传递一个函数，这个函数要求返回一个Promise或则是一个对象(Promise | any)
// 函数会有一个响应对象形参，然后可以通过对形参的data对象处理，实现通用业务的一个拦截处理
Axios.interceptors.response.use(function(response) {
    // console.log(arguments)
    // 判断后端返回的状态码是否是403，如果是403，直接抛出一个异常，中断请求，然后提示用户token失效，需要重新登录
    if (response.data.code === 403) {
        // throw new TypeError('用户的token错误或已失效，需要用户重新登录获取新的token')
        // 还可以使用Promise返回错误
        // return Promise.reject('用户的token错误或已失效，需要用户重新登录获取新的token')
        return response
    } else {
        // 正常的业务直接返回对象
        return response
    }
})

// 封装一个ajax请求方法
function ajaxFunc(req) {

    // 如果url地址没有传递，直接报错 -- JS是主线程运行应用，所以可以使用异常抛出中断当前的线程
    if (!req.url) {
        throw new SyntaxError('请求的url参数是必传的')
    }

    return new Promise(resolve => {

        // 把动态数据 url、method、params、data 抽取出来
        // 应该用封装后的一个请求实例对象
        // axios.request({
        Axios.request({
            // 设置请求地址
            url: req.url,
            method: req.method || 'POST',
            // 是请求的基础地址
            // baseURL: 'http://www.shuiyue.info:12600',
            // 所有的请求都加上一个/apis，然后服务器会把它进行一个代理
            // baseURL: '/apis', // 这个请求地址长什么样子？http://localhost:16666/apis/user/app/code
            // 请求头
            // headers: {token: 'test token'},
            // 超时配置 -- 设置请求的最大时长
            // timeout: 5000,
            // params参数配置 -- 它的参数会自动拼接到url地址上
            params: req.params || {},
            // data参数 -- 不能再get请求中使用，它是请求体参数
            data: req.data || {},
            baseURL: req.baseURL || '/apis'
        // }).then(data => {
            // 请求返回的是一个response对象，希望得到数据
            // console.log(data.data)
        }).then( ({ data }) => {
            // 可以对response对象进行解构取值
            // 返回数据
            resolve(data)
        }).catch(e => {
            console.log('----------------- 请求失败')
            resolve(e)
        })
    })

}

export default ajaxFunc